package com.project.fortuneteller.controller.intecepter;


import cn.hutool.core.util.ObjectUtil;
import com.project.fortuneteller.config.RedisConstant;
import com.project.fortuneteller.context.UserContext;
import com.project.fortuneteller.exception.UserBusinessErrorEnum;
import com.project.fortuneteller.exception.UserBusinessException;
import com.project.fortuneteller.pojo.UserInfo;
import com.project.fortuneteller.utils.SpringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RScoredSortedSet;
import org.redisson.api.RedissonClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Objects;

@Slf4j
@Configuration
public class GlobalAuthIntecepter implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理之前进行拦截
        // 返回true表示继续向下执行，返回false则中断执行。
        // DEV_MOON_TOKEN
        String header = request.getHeader("authorization");

        log.info("header: {}",header);
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        RedissonClient redissonClient = (RedissonClient) applicationContext.getBean("redissonClient");

        log.info("getRequestURL: {}",request.getRequestURI());

        // 预检请求 或者是/swagger-ui.html 的请求直接通过，不加拦截
        if(Objects.equals(request.getMethod(), "OPTIONS")  ){
            return Boolean.TRUE;
        }
        // 1760931912820
        if(ObjectUtil.isEmpty(header) || ObjectUtil.isNull(header) ){
            String message = UserBusinessErrorEnum.USER_NOT_LOGIN.getMessage();
            System.out.println("error message:" + message);
            // 错误码不能定义成400 否者会失效
            UserBusinessErrorEnum userBusinessErrorEnum = UserBusinessErrorEnum.USER_NOT_LOGIN;
            throw new UserBusinessException(userBusinessErrorEnum);
        }

        RBucket<UserInfo> redisUserInfo = redissonClient.getBucket(header);

        long expireTime = redisUserInfo.remainTimeToLive();
        log.info("remainTime: {}" , expireTime);

        if (expireTime<0 ) {
            // 过期后删除键
            redisUserInfo.delete();
            UserBusinessErrorEnum userLoginTimeout = UserBusinessErrorEnum.USER_LOGIN_TIMEOUT;
            throw new UserBusinessException(userLoginTimeout);
        }


        UserInfo userInfo = redisUserInfo.get();
        // 封装 ThreadLocal 上下文对象
        // 将对象 保存在 当前线程的上下文中
        UserContext.setUserInfo(userInfo);

        // 在线人数统计功能
        RScoredSortedSet<String> sortedSet = redissonClient.getScoredSortedSet(RedisConstant.DEV_INLINE_PERSON_NUM);
        boolean add = sortedSet.add(System.currentTimeMillis() + expireTime, userInfo.getId());

        if(add){
            log.info("用户添加成功");
        }else{
            log.info("用户已存在");
        }


        return Boolean.TRUE;
    }

}
